home *** CD-ROM | disk | FTP | other *** search
- /* opalpcd.c v0.30
- program to display PhotoCD pictures and save them to OpalVision
- files and display. This will read the file and convert it to a
- virtual screen which may be saved in a JPEG or IFF24 file.
-
-
- This program is based on hpcdtoppm by Hadmut Danisch
-
- OH Yeah, Its going to take helluva lotta memory
- base =1.5m, 4base=6meg, 16base =24m
- Picked up and adapted by BAZZ on 3-2-93
- I will have to use RGB toOV, and may have to break it up into
- several modules to save RAM.
-
- Additions © BAZZ 1993, and similar conditions as Hadmut states apply, that
- is pass it around all you want, but dont take credit for it (unless you
- add to it) and don't distribute for profit. This is intended to enrich the
- Amiga community and is for educational purposes only.
-
- I MAINTAIN HADMUT'S CONVENTION OF LEVEL 2 FILE AND MEMORY ACCESS WHICH CLOSES
- OR FREES AUTOMATICALLY UPON EXIT, AND IS MORE PORTABLE CODE.
-
-
- Rev .20
- As of 3-8 I had resolutions up thru Base working. The decompression isnt
- working right on 4Base and is being looked into. This will print out on an
- OpalVision screen. The library should allown IFF24 conversion and is included
- with many utilities. It might work without it but not guaranteed.
-
-
- Rev .30
- As of April 15, Resolution 4 is working now but takes a machine with
- 12 Meg of FAST Ram to load the entire picture. With 6-8 Meg fast you can
- crop parts out. Unfortunately the requirement is h*w*6, and the only way
- around it is radically rewriting the code. I have no incentive to do this
- since I have enough memory, and resolution 5 (3072x2048) isn't working yet.
- doing a 'dummy test' found that none of the compression beyond the first
- Luma compression worked. When this works, I'll consider it.
- The Overview mode is fixed now and shows 16 small pictures on a page.
- Pressing right button goes to next page, and pressing left exits. When
- the top is reached it cycles back to the first page.
- Also fixed a bug that left Opal screen open if an error is encountered.
-
- Rev .40
- May 12, 1993
- Allows start of slideshow( -p) mode anywhere. Slideshow keeps repeating
- until mouse held down. When last picture is shown it goes back to first
- Uses virtul memory sort of.
- For resolutions 4 and 5, option -v allows
- loading and most conversion then storing to hard disk. Memory is freed and
- then reloaded in small bits to the Opalvision screen which now has the
- lion's share of memory available. Adds a few seconds, but is the ONLY way
- most can use resolution 5.
-
- This was compiled using SAS/C® V 6.02
- */
-
-
- /* hpcdtoppm (Hadmut's pcdtoppm) v0.1
- * Copyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
- * Permission to use and distribute this software and its
- * documentation for noncommercial use and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation. It is not allowed to sell this software in
- * any way. This software is not public domain.
- Here it is. This file IS supporting documentation -BAZZ
-
- */
- #define xDEBUG
- /* extern char *malloc(); */
-
- #include <proto/all.h>
- #include <opal/opallib.h>
- #include <graphics/gfxbase.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <String.h>
- #include <dos.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <libraries/asl.h>
- #include <exec/execbase.h>
- #include <graphics/gfxmacros.h>
- #include <hardware/custom.h>
- #
- #include <devices/timer.h>
- #include <workbench/startup.h>
- #include <time.h>
-
- #include <math.h> /* lets give it something to REALLY Render */
- #include <m68881.h> /* use co pro wherever possible */
-
- typedef unsigned long dim;
-
- #define BaseW ((dim)768)
- #define BaseH ((dim)512)
-
- #define DISP_W 736
- #define DISP_H 476 /* hi-res screen */
-
-
- #define slen 3072 /* try to keep all defines here! */
-
-
- #define SECSIZE 0x800 /* 2k for CDrom */
- #define RBMASK 0x0400
-
- #define ASKIP { argc--; argv ++;}
- #define ABACK { argc++; argv --;} /* added incase we have something wrong */
-
- #define SeHead 2
- #define L_Head (1+SeHead)
-
- #define SeBase16 18
- #define L_Base16 (1+SeBase16)
-
- #define SeBase4 72
- #define L_Base4 (1+SeBase4)
-
- #define SeBase 288
- #define L_Base (1+SeBase)
- #define S_DEFAULT S_Base /* default to base */
-
-
- #define VERS 40 /* current version */
- #define VLINES 32 /* number of lines to pull in at once for virt memory */
-
-
- enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
- E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,
- E_IMP,E_COOL,E_OVD,E_SCR,E_NCDS,E_ABT };
-
- enum TURNS { T_NONE,T_RIGHT,T_LEFT };
-
- enum SIZES { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,
- S_4BaseHC, S_Over, };
-
- /* Default taken when no size parameter given */
-
-
- char *lumfn="OpcdLuma.tmp"; /* filenames for working files */
- char *c1fn= "OpcdChr1.tmp";
- char *c2fn= "OpcdChr2.tmp";
-
- struct ph1 /* the header for the Photo CD file */
- {char id1[8];
- char ww1[14];
- char id2[20];
- char id3[4*16+4];
- short ww2;
- char id4[20];
- char ww3[2*16+1];
- char id5[4*16];
- char idx[11*16];
- } ;
-
-
- struct ifhdr{ /* structure header for header */
- ULONG type; /* should be OPif */
- ULONG plane;/* should be LUMA, CHR1, or CHR2 */
- USHORT width; /* typ 1536 */
- USHORT height;/* typ 1024 */
- USHORT vers;
- USHORT misc; };
-
- struct ifhdr ih={ 0x4F506966,0x4B554C41,1536,1024,40,0}; /* default */
- struct _implane
- {dim mwidth,mheight, iwidth,iheight;
- byte *im;
- };
- typedef struct _implane implane;
-
- /* PROTOTYPES */
- void getout(void), cleanup(enum ERRORS);
- void telltime(char *, unsigned int *);
- int Display_Mode_Check(void);
- int DoOpal(int,int, char *fname),VirtOpal(int,char *);
- int GetNextPic(int,int);
- int TurnOpal( struct OpalScreen *, UBYTE **, int,int,int,int,int);
- struct OpalScreen *OpenOpal(void);
- static void planealloc(implane *,dim,dim);
-
- static void interpolate(implane *);
- static void ycctorgb(dim,dim, implane *,implane *,implane *);
- static void readhqt(dim,dim,dim);
- static void readhqtsub(struct pcdhqt *source,struct myhqt *ziel,int *anzahl);
-
-
- static void decompress(dim,dim,implane *,implane *, implane *);
- static void clear(implane *,int);
- static void druckeid(void );
- static void sharpit(implane *);
- int storeplane(implane *,char *); /* save it */
- void planefree(implane *); /* free contents of a plane */
- enum ERRORS readplain(dim,dim,implane *,implane *,implane*);
-
- /* Global Variables */
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct OpalBase *OpalBase;
- struct OpalScreen *OScrn;
- struct WBArg *WBArg;
- BOOL FromWB;
-
- __far UBYTE *Button = (UBYTE *)0xbfe001; /* Nasty */
- __far UWORD *RButton= (UWORD *)0xdff016; /* read right button */
-
- __far extern struct Custom custom; /* for registers */
-
-
- /* bit 10, use dff016 for right */
- #define RIGHT custom.joy1dat & 2
- #define LEFT custom.joy1dat & 0x200
- #define UP ( custom.joy1dat & 1 )
- #define DOWN ( custom.joy1dat & 0x100)
- #define FIRE (*Button & 0x80)
-
- static FILE *fin=0,*fout=0;
- static char *pcdname=0,*ppmname=0;
- static char nbuf[100];
- static byte sbuffer[SECSIZE]; /* Increase, allow for reading 2 sectors */
- static byte sbufaux[SECSIZE];
- static byte lumadump[3100]; /* for null char for mode 6 */
-
- static int do_sharp,backdrop,crop,virt;
- static int init;
-
- implane Luma, Chroma1,Chroma2,C1t,C2t; /* make them global */
- dim w,h;
- static int version,cropx,cropw,cropy,croph,jpeg; /* coords for cropping */
- int pstart;
- unsigned int clock1[2],clock2[2]; /* for timer */
- enum TURNS turn=T_NONE;
-
-
-
-
-
-
- /* Using preprocessor for inline-procs */
- #ifdef DEBUG
- #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) cleanup(E_READ);\
- fprintf(stderr,"S-Position %x\n",ftell(fin)); }
- #else
- #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) cleanup(E_READ);}
- #endif
-
-
- #define SKIP(n) { if (fseek(fin,(n),1)) cleanup(E_READ);}
- #define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
-
- #define READBUF fread(sbuffer,sizeof(sbuffer),1,fin)
- #define READ2BUF fread(sbuffer,sizeof(sbuffer),2,fin) /* allow for 2 sectors or 4K */
-
- #define TRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b) ))
- #define NORM(x) x=TRIF(x,0,255,0,x,255)
-
- void getout()
- {
- cleanup(E_ABT);
- } /* just to get out, this is the ^C trap */
-
-
- void cleanup(e) /* leave and display why */
- enum ERRORS e;
- {
- switch(e)
- {case E_NONE: return;
- case E_IMP: fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
- case E_READ: fprintf(stderr,"Error while reading.\n"); break;
- case E_WRITE: fprintf(stderr,"Error while writing.\n"); break;
- case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
- case E_ARG: fprintf(stderr,"Arguments !\n");
- fprintf(stderr,"OpalPCD Access for Amiga V. %d \n",VERS);
- fprintf(stderr,"Usage: opalpcd [options] pcd-file [IFF24file]\n");
- fprintf(stderr,"Opts:\n");
- fprintf(stderr," -i Give some (buggy) informations from fileheader\n");
- fprintf(stderr," -s Apply simple sharpness-operator on the Luma-channel\n");
- fprintf(stderr," -d Show differential picture only \n");
- fprintf(stderr," -r Rotate clockwise for portraits\n");
- fprintf(stderr," -l Rotate counter-clockwise for portraits\n");
- fprintf(stderr," -a Enable AutoSync for Opal Display \n");
- fprintf(stderr," -p Presentation SLideShow all Images in cd0:\n");
- fprintf(stderr," -b To place image as backdrop upon exit \n");
- fprintf(stderr," -c x y [w] [h] crop output image. \n");
- fprintf(stderr," where x,y =coords of upper left. w&h are size\n");
- fprintf(stderr," -j [quality] Save in Jpeg instead of IFF24 \n");
- fprintf(stderr," -v virtual mem. Uses H Drive Modes 4&up only \n");
-
-
- fprintf(stderr," -O Extract thumbnails from Overview file\n");
- fprintf(stderr," -1 Extract 128x192 from Image file\n");
- fprintf(stderr," -2 Extract 256x384 from Image file\n");
- fprintf(stderr," -3 Extract 512x768 from Image file\n");
- fprintf(stderr," -4 Extract 1024x1536 from Image file\n");
- fprintf(stderr," -5 Extract 2048x3072 from Image file\n");
- fprintf(stderr," -6 Extract 1024X1536 Enhanced Chroma\n");
- break;
- case E_OPT: fprintf(stderr,"These Options are not allowed together.\n");break;
- case E_MEM: fprintf(stderr,"Not enough memory !\n"); break;
- case E_HUFF: fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
- case E_SEQ: fprintf(stderr,"Error in Huffman-Sequence\n"); break;
- case E_SEQ1: fprintf(stderr,"Error1 in Huffman-Seque nce\n"); break;
- case E_SEQ2: fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
- case E_SEQ3: fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
- case E_SEQ4: fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
- case E_SEQ5: fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
- case E_SEQ6: fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
- case E_SEQ7: fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
- case E_POS: fprintf(stderr,"Error in file-position\n"); break;
- case E_COOL: fprintf(stderr,"Cannot opan opal.library \n"); break;
- case E_OVD: fprintf(stderr,"Opalvision error \n"); break;
- case E_SCR: fprintf(stderr,"You need a 15KHZ scan rate(genlockable) screen \n"); break;
- case E_NCDS: fprintf(stderr," Slide Show available in Base/4 and Base Only \n"); break;
- case E_ABT: fprintf(stderr," User Aborted with CTRL-C \n");
- default: fprintf(stderr,"Unknown error %d ???\n",e);break;
- }
- if(fin) fclose(fin); /* close files */
- if(fout) fclose(fout);
- if (OpalBase!=NULL) /* if we did play with OpalVision, lets fix things */
- { AmigaPriority();
- if (OScrn) FreeScreen24 (OScrn); /* oops, forgot */
- CloseScreen24 ();
- CloseLibrary ((struct Library *)OpalBase);
- }
-
- exit(e); /* return the error */
- }
-
-
- static void planealloc(p,width,height)
- implane *p;
- dim width,height;
- {
- p->iwidth=p->iheight=0;
- p->mwidth=width;
- p->mheight=height;
- /* this is level II and freed by c startup, we should fix later */
- p->im = ( byte * ) malloc (width*height);/* we know a byte is 1! */
- if(!(p->im)) cleanup(E_MEM);
- }
-
- void planefree(implane *p) /* simply free the plane added 5/6/93 */
- {
- if ( p->im) free(p->im); /* that's it! */
-
- }
-
-
-
- main(argc,argv) /* MAIN */
- int argc;
- char **argv;
- {int i,bildnr;
- char *opt;
- int do_auto,cd_offset,do_info,do_diff,do_overskip,do_slide;
- int cccnt=0,Err,a,orun=0;
- enum SIZES size=S_UNSPEC;
- UBYTE *rgbps[3];
- enum ERRORS eret;
- pstart=1; /* normally start at 1 */
- ih.vers=VERS; /* current version */
- do_info=do_auto=do_diff=do_overskip=do_sharp=0;
- backdrop=do_slide=crop=jpeg=virt=0; /* default to 0 */
- Luma.im=Chroma1.im=Chroma2.im = NULL;
- ASKIP;
- init=0;
- onbreak(getout); /* try to set a ctrl c trap */
- /* parse input line */
- cropx=cropy=-1; /* default meaning not set */
- cropw=DISP_W; croph=DISP_H; /* default to one full screen */
- while((argc>0) && (**argv=='-')) {
- opt= (*argv)+1;
- ASKIP
-
- /* don't screw with anything between the while and this comment */
-
- if(!strcmp(opt,"c")) /* crop coordinates */
- { /* now fetch coords */
- crop=255;
- if( isdigit( **argv) && (argc >0)) { /* see if following is a # */
- cropx=atoi(*argv); cccnt++;
- ASKIP
- if(isdigit(**argv) && argc ){ /* look for cropy */
- cropy=atoi(*argv); cccnt++;
- ASKIP
- if(isdigit(**argv) && argc ){ /* look for cropw */
- cropw=atoi(*argv); cccnt++;
- ASKIP
- if(isdigit(**argv)&&argc ){ /* look for croph */
- croph=atoi(*argv); cccnt++;
- ASKIP;
-
- /* we got all four if we got here */
- }
- else { cropw=DISP_W; } /* cant use w w/o h*/
- }
-
- }
- else { cropx= -1; }
- }
- /* couldnt get cropx */
- printf( "cropping left = %d top = %d width = %d height =%d\n",cropx,cropy,cropw,croph);
- continue;
- }
-
-
- if(!strcmp(opt,"j")) /* select jpeg file mode */
- {
- if (isdigit ( **argv) && (**argv != '-')&&(argc>0)) {
- /* look for quality factor */
- jpeg=atoi(*argv);
- ASKIP
- }
- else { jpeg = 84; } /* assume 84 if not spec */
- if (jpeg <1 ) jpeg=1;
- if (jpeg >100) jpeg=100;
-
- continue;
- }
- /* printf("past my options %d \n",argc); */
-
- if(!strcmp(opt,"a")) /* slide show mode */
- {if (!do_auto ) do_auto=255;
- else cleanup(E_ARG);
- continue;
- }
-
-
- if(!strcmp(opt,"p")) /* slide show mode */
- {if (!do_slide ) do_slide=255;
- else cleanup(E_ARG);
- continue;
- }
- if(!strcmp(opt,"v")) /* Virtual memory mode, size 4 and up please! */
- {if (!virt ) virt=255;
- else cleanup(E_ARG);
- continue;
- }
-
-
-
- if(!strcmp(opt,"r"))
- {if (turn == T_NONE) turn=T_RIGHT;
- else cleanup(E_ARG);
- continue;
-
- }
-
- if(!strcmp(opt,"l"))
- {if (turn == T_NONE) turn=T_LEFT;
- else cleanup(E_ARG);
- continue;
- }
-
- if(!strcmp(opt,"i"))
- { if (!do_info) do_info=1;
- else cleanup(E_ARG);
- continue;
- }
-
-
- if(!strcmp(opt,"d"))
- { if (!do_diff) do_diff=1;
- else cleanup(E_ARG);
- continue;
- }
- if(!strcmp(opt,"b"))
- { if (!backdrop) backdrop=1;
- else cleanup(E_ARG);
- continue;
- }
-
- if(!strcmp(opt,"s"))
- { if (!do_sharp) do_sharp=1;
- else cleanup(E_ARG);
- continue;
- }
-
-
- if(!strcmp(opt,"x"))
- { if (!do_overskip) do_overskip=1;
- else cleanup(E_ARG);
- continue;
- }
-
-
-
- /* get desired size */
- if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1")) || (!strcmp(opt,"128x192")))
- { if (size == S_UNSPEC) size = S_Base16;
- else cleanup(E_ARG);
- continue;
- }
- if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2")) || (!strcmp(opt,"256x384")))
- { if (size == S_UNSPEC) size = S_Base4;
- else cleanup(E_ARG);
- continue;
- }
- if((!strcmp(opt,"Base" )) || (!strcmp(opt,"3")) || (!strcmp(opt,"512x768")))
- { if (size == S_UNSPEC) size = S_Base;
- else cleanup(E_ARG);
- continue;
- }
- if((!strcmp(opt,"4Base" )) || (!strcmp(opt,"4")) || (!strcmp(opt,"1024x1536")))
- { if (size == S_UNSPEC) size = S_4Base;
- else cleanup(E_ARG);
- continue;
- }
- if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5")) || (!strcmp(opt,"2048x3072")))
- { if (size == S_UNSPEC) size = S_16Base;
- else cleanup(E_ARG);
- continue;
- }
- if( (!strcmp(opt,"4BC" )) || (!strcmp(opt,"6")) )
- { if (size == S_UNSPEC) size = S_4BaseHC;
- else cleanup(E_ARG);
- continue;
- }
-
-
- if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0")) || (!strcmp(opt,"O")))
- { if (size == S_UNSPEC) size = S_Over;
- else cleanup(E_ARG);
- continue;
- }
-
- fprintf(stderr,"Unknown option: -%s\n",opt);
- cleanup(E_ARG);
- }
-
-
- /* printf( "loop completed \n");*/
-
- if(size==S_UNSPEC) size=S_DEFAULT;
-
- if((argc<1) && !(do_slide)) cleanup(E_ARG); /* forgive lack of name if slide */
- pcdname= *argv;
- ASKIP;
-
- if(argc>0)
- {ppmname= *argv;
- ASKIP;
- }
- if ( isdigit(*pcdname) && isdigit ( *(pcdname+1) ) && (strlen(pcdname)==2))
- { /*two digit number, use as easy file name */
- pstart= (*pcdname - 48)*10 ;
- pstart+=( *(pcdname+1) -48);
- printf("starting at %d \n",pstart);
- strcpy(nbuf,"CD0:PHOTO_CD/IMAGES/IMG00"); /* build name */
- strcat(nbuf,pcdname);
- strcat(nbuf,".PCD");
- pcdname=nbuf; /* transfer pointer */
- if (size == S_Over) pcdname ="CD0:PHOTO_CD/OVERVIEW.PCD";
- /* for an overview, use this file 4-15-93 */
- }
- if(argc>3) cleanup(E_ARG);
- /* if((size==S_Over) && (!ppmname)) cleanup(E_ARG); */
- if(do_info && (size==S_Over)) cleanup(E_OPT);
- if(do_diff && (size != S_4Base) && (size != S_16Base)&& (size != S_4BaseHC)) cleanup(E_OPT);
- if(do_overskip) cleanup(E_IMP);
- if(do_overskip && (size != S_Base4) && (size != S_Base16)) cleanup(E_OPT);
- if(do_slide) { /* for auto */
-
- ppmname=NULL; /* we wont save file */
- if(!(pcdname))
- pcdname="CD0:PHOTO_CD/IMAGES/IMG0001.PCD";
- /* start at beginning if not spec */
- if (size > S_Base) {
- printf( "can't slideshow above base res \n");
- cleanup(E_ARG); }
- }
- /* printf( " infile %s jpeg %d slide %d argc %d \n",pcdname,jpeg,do_slide,argc);
- */
- #ifdef DEBUG
- fprintf(stderr,"Turn %d Size %d Pcd %s ppm %s\n",turn,size,pcdname,ppmname);
- #endif
-
- if(!(fin=fopen(pcdname,"r"))) cleanup(E_READ);
- if(do_info) druckeid(); /* show ID code */
- OpalBase = (struct OpalBase *) OpenLibrary ("opal.library",0L);
- if (OpalBase==0L) /* opal opal library */
- cleanup (E_COOL);
- OScrn = NULL;
- i=timer(clock1); /* get clock */
-
- switch(size) /* perform the operation based on size */
- {
- case S_Base16: w=BaseW/4;
- h=BaseH/4;
- if (do_slide) cleanup( E_NCDS);
-
- planealloc(&Luma ,w,h);
- planealloc(&Chroma1,w,h);
- planealloc(&Chroma2,w,h);
-
- SEEK(L_Head+1);
- cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
-
- interpolate(&Chroma1);
- interpolate(&Chroma2);
-
- ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
- /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
-
-
- /* writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);*/
- OpenOpal();
- DoOpal(do_auto,do_slide,ppmname);
- break;
-
- case S_Base4: w=BaseW/2;
- h=BaseH/2;
- planealloc(&Luma ,w,h);
- planealloc(&Chroma1,w,h);
- planealloc(&Chroma2,w,h);
-
- SEEK(L_Head+L_Base16+1);
- cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
-
- interpolate(&Chroma1);
- interpolate(&Chroma2);
-
- ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
- /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
-
- OpenOpal();
- DoOpal(do_auto,do_slide,ppmname);
- break;
-
- case S_Base: w=BaseW;
- h=BaseH;
-
- planealloc(&Luma ,w,h);
- planealloc(&Chroma1,w,h);
- planealloc(&Chroma2,w,h);
- if (!OpenOpal()) cleanup(E_OVD);
-
- SEEK(L_Head+L_Base16+L_Base4+1);
- cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
- interpolate(&Chroma1);
- interpolate(&Chroma2);
- ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
- /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
- DoOpal( do_auto,do_slide,ppmname); /* do all the nice OpalVision stuff */
- break;
- case S_4BaseHC:
- case S_4Base: w=BaseW*2;
- h=BaseH*2;
- if (do_slide) cleanup( E_NCDS);
- planealloc(&Luma,w,h); /* thats almost 5 meg! */
- planealloc(&Chroma1,w,h);
- planealloc(&Chroma2,w,h);
- if ( !virt){ /* open it here if NOT virtual mem */
-
- if (!OpenOpal()) {
- printf("Can't open Opal Screen. Try a smaller area \n");
- cleanup(E_OVD); }
- }
- SEEK(L_Head+L_Base16+L_Base4+1);
- /* THIS IS ONLY THE SAME AS MODE 3! */
- cleanup(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
-
- interpolate(&Luma);
- interpolate(&Chroma1);
- interpolate(&Chroma1);
- interpolate(&Chroma2);
- interpolate(&Chroma2);
-
- if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
- /* above only clears */
-
- cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
-
-
- SEEK(cd_offset + 4); readhqt(w,h,1);
-
- SEEK(cd_offset + 5);
- decompress(w,h,&Luma,0,0);
- /* add full LUMA res */
- if (size== S_4BaseHC) { /* we are trying to fill colors*/
- cd_offset=ftell(fin);
- if(cd_offset % SECSIZE) cleanup(E_POS);
- cd_offset/=SECSIZE;
- SEEK(cd_offset+12);
- readhqt(w*2,h*2,3);
- printf(" gonna decomp the chroma now\n");
- SEEK(cd_offset+14);
- decompress(w*2,h*2,0,&Chroma1,&Chroma2);
-
- /* try adding full chroma from highest sampling */
- }
- if (virt) { /* do this if using virtual mem */
- printf("Virtual memory mode selected, now saving \n");
- ih.width=w; ih.height=h;
- i=storeplane(&Luma,lumfn); /* store Luma plane*/
-
- planefree(&Luma); /* free it up */
- if (i) { printf("Error %d storing intermediate file, too little disk space? \n",i);
- cleanup(E_WRITE); }
- i=storeplane(&Chroma1,c1fn);
- planefree(&Chroma1);
- i=storeplane(&Chroma2,c2fn);
- planefree(&Chroma2);
- if (i) { printf("Error %d storing intermediate file, too little disk space? \n",i);
- cleanup(E_WRITE); }
- if (!OpenOpal()) {
- printf("Can't open Opal Screen. Try a smaller area \n");
- cleanup(E_OVD);
- }
- VirtOpal(do_auto,ppmname);
- }
- else { ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
- /* normal mode, do all in one swell foop. Needs 12M fast*/
- telltime("Time to Decode Picture:",clock1);
- DoOpal( do_auto,do_slide,ppmname); /* try disp some */
- }
- break;
-
- case S_16Base: w=BaseW*4;
- h=BaseH*4;
- if (do_slide) cleanup( E_NCDS);
- planealloc(&Luma,w,h);/* full luma no matter what */
- SEEK(L_Head+L_Base16+L_Base4+1);
-
- if (virt){ /* Virt Mem. Just alloc enuf chroma to read PCD!*/
- planealloc(&C1t,w/8,h/8);/* just get the data for now */
- planealloc(&C2t,w/8,h/8);/* theyre only 98K each */
- cleanup(readplain(w/4,h/4,&Luma,&C1t,&C2t));
- }
- else {planealloc(&Chroma1,w,h);/* normal, got 20-40Meg??*/
- planealloc(&Chroma2,w,h);
- OpenOpal();
- cleanup(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
- interpolate(&Chroma1);
- interpolate(&Chroma1);
- interpolate(&Chroma2);
- interpolate(&Chroma2); /* expand chroma */
- }
-
- interpolate(&Luma); /* expand luma to 1536x1024 */
-
- cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
- SEEK(cd_offset + 4);
- readhqt(w/2,h/2,1);
- SEEK(cd_offset + 5);
- decompress(w/2,h/2,&Luma,0,0); /* decomp luma to 1536x1024*/
- interpolate(&Luma); /* spread Luma to 3072x2048 */
- cd_offset=ftell(fin);
- if(cd_offset % SECSIZE) cleanup(E_POS);
- cd_offset/=SECSIZE;
-
- SEEK(cd_offset+12);
- readhqt(w,h,3);
- if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
- SEEK(cd_offset+14); /* we are in position for final decomp */
- if (virt) { /* Again, do this in virtual mode */
- /* takes about 10 Meg of HD space */
- ih.width=w; ih.height=h; /* store size */
- printf("Virtual memory selected, saving Mode 5 Luma \n");
-
- decompress(w,h,&Luma,&Chroma1,&Chroma2);/* decomp the final Luma */
- /* CODE MOVED TO DECOMPRESS TO STORE LUMA AND SETUP CHROMA PLANES */
- /* THIS BECAUSE DECOMPRESS IS NOT TOO REENTRANT AND I DONT WANT TO F*** WITH IT*/
-
- /* at this point, we should have two 1536x1024 chroma planes
- unless we got a huffman error, etc */
- ih.width=w/2; ih.height=h/2; /* chroma planes 1/4 size*/
-
- i=storeplane(&Chroma1,c1fn);
- planefree(&Chroma1);/* store and free them */
- i=storeplane(&Chroma2,c2fn);
- planefree(&Chroma2);
- if (i) { printf("Error %d storing intermediate file, too little disk space? \n",i);
- cleanup(E_WRITE); }
- if (!OpenOpal()) {
- printf("Can't open Opal Screen. Try a smaller area \n");
- cleanup(E_OVD);
- }
- /* NOTE: WE WILL DO FINAL INTERPOLATION OF CHROMA WHEN
- WE LOAD IT BACK IN. This saves 9M HD+Xfer time */
- VirtOpal(do_auto,ppmname);
- }
- else { /* 'Normal' Mode, that is, if you own Samsung Memory division */
- decompress(w,h,&Luma,0,0);
- interpolate(&Chroma1);
- interpolate(&Chroma2);
-
- ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
- DoOpal(do_auto,0,ppmname); /* display what we can */
-
- }
- /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
- break;
-
- case S_Over: /* we are going to render some small images */
- w=BaseW;
- h=BaseH; /* use a full size screen for now */
-
- planealloc(&Luma ,w/4,h/4); /* allocate for tiny images */
- planealloc(&Chroma1,w/4,h/4);
- planealloc(&Chroma2,w/4,h/4);
- if( !(Chroma2.im) ) cleanup(E_MEM);
- rgbps[0]=Luma.im;
- rgbps[1]=Chroma1.im; /* copy pointers */
- rgbps[2]=Chroma2.im;
- if (!( OpenOpal())) cleanup(E_OVD);
- OScrn->Pen_R=OScrn->Pen_G=0;
- OScrn->Pen_B=100; /* blue background */
- for(orun=0; orun <8 && !feof(fin); orun++){ /* loop each page (16 pix) */
- SetScreen24(OScrn); /* clear and install bkgrnd */
- for(bildnr=orun<<4;!feof(fin) && (bildnr< (orun+1)<<4);bildnr++){ /* ea pic*/
- SEEK(5+SeBase16*bildnr);
-
- eret=readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2);
- if(eret==E_READ) break;
- cleanup(eret);
-
- interpolate(&Chroma1);
- interpolate(&Chroma2);
-
- ycctorgb(w/4,h/4,&Luma,&Chroma1,&Chroma2);
- /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
- RGBtoOV(OScrn,rgbps,(bildnr&3)*190,((bildnr>>2)&3)*120,192,128);
- /* render each of 16 in */
-
- }
- AutoSync24(do_auto);
- Err = (long)LowMemUpdate24 (OScrn,0);
- if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
- { AutoSync24 (do_auto);
- /* Err = (long)LowMemUpdate24 (OScrn,6); */
- }
- /* end of main loop. If we save img, save last image */
- while ( ( *Button &0x040) &&(*RButton & RBMASK) ){ /* button for single show */
- Delay(10); } /* if no button down wait */
-
- if (!(*RButton & RBMASK)){ /* right pushed */
-
- /* next page and continue */
- if ( feof(fin) ){ orun=-1; /* if we hit end of pix, start anew */
- rewind(fin); /* set position back to start */
- Delay(5); }
- }
- else orun=20; /* put loop var high to exit, was left mouse button */
-
- } /* end of running loop, past here were done */
-
- if ( (OScrn) && (ppmname) ){ /* we can save file */
- if (jpeg)
- a=SaveJPEG24(OScrn,ppmname,NULL, jpeg);
- else
- a=SaveIFF24(OScrn,ppmname, NULL,NULL);
- if (a) printf( "iff save error # %d couldn't save picture\n",a);
- else printf( "file saved as %s \n",ppmname);
- }
-
- if ( backdrop){ /* we want to leave image as backdrop */
- AmigaPriority ();
- DualDisplay24 ();
- Delay (2L);
- LatchDisplay24 (TRUE);
- Delay (2L);
-
- }
- FreeScreen24 (OScrn); /* clean up here */
- CloseScreen24();
- return(0);
-
- break;
-
- default: cleanup(E_INTERN);
- }
- /* WE USE LEVEL 2 FILE&MEM HANDLING, IF WE FORGET TO FREE OR CLOSE, NO HARM DONE*/
- exit(0); /* exit normal */
- }
-
- #undef ASKIP
-
-
-
- struct OpalScreen *OpenOpal() /* display and save OV */
- /* This just appropriats and opens the Opal Screen */
- {
- long scm;
- int dw,dh;
-
- scm= OVERSCAN24;
-
- if (!Display_Mode_Check())
- cleanup( E_SCR); /* check for 15KHZ res */
- dw= DISP_W/2; dh=DISP_H/2;
- if ( w> 400) {
- scm |= ILACE24 | HIRES24; /* if base & up do hires lace */
- dw=DISP_W; dh=DISP_H;
- if ( !crop) cropx=cropy=0;
- }
- else {
- cropx= (dw-w+2)/2; /* center picture tiny res no crop possible */
- cropy= (dh-h+2)/2;
- }
-
- if ( !crop ) {
- if (turn){
- OScrn = CreateScreen24(scm,max(dw,h),max(dh,w)) ;
- }
- else
- OScrn = CreateScreen24(scm,max(dw,w),max(dh,h)) ;
- /* same size virtual screen */
- }
- else { /* set up for cropping */
- if ((cropw>w) || (cropw < 32)) cropw=dw; /* limit width */
- if ((croph>h) || (croph < 20)) croph=dh; /* default to center if bad*/
- if ( (cropx < 0) || (cropy <0 ) || (cropx>w) || (croph>h) ) {
- /* invalid or unspecified values */
- cropx=(w-cropw)/2; /* center */
- cropy=(h-croph)/2; /* a normal 736x480 is disp if numbers bad */
- }
- OScrn = CreateScreen24(scm,cropw,croph);
- /* create just for disp to test higher mode */
- }
-
- if ( !OScrn){
- printf( "Can't Alloc Opal Screen, Try a smaller area \n");
- }
- /* create the virtual screen to plop the data in */
- return(OScrn);
- }
-
- int VirtOpal(int asy, char *fname) /* fill display and save OV */
- { /* virtual memory ONLY size 4&up(1536x1024 or 3072x2048
- May 7, 1993
- THIS IS USED INSTEAD OF DoOpal and TurnOpal. It reads back the raw data
- 32 lines at a time and does final conversion and puts them in Opal screen */
- int a,maxy,nrep,dw,dh,i;
- long Err;
- register int x,y,yi;
- byte *rgbuf[4],*lb1,*lb2,*op1,*np1,*up1,*op2,*np2,*up2; /* pointers into array */
- FILE *fpl,*fp1,*fp2; /* pointers to three files */
- struct ifhdr hl,h1,h2; /* header data */
- planealloc(&Luma ,w,VLINES);/* make some mini Planes to reload parts */
- planealloc(&Chroma1,w,VLINES+4);/* should be 150 or 300K */
- planealloc(&Chroma2,w,VLINES+4);/* a little xtra in chroma for rollover */
- lb1=malloc(w); /* small buffers for shuffling lines in interp */
- lb2=malloc(w); /* each = width for long lines */
- if ( !lb2) cleanup(E_MEM); /* not enuf mem, need only check second one */
- maxy=h;
- if(crop) maxy=cropy+croph+VLINES-1; /* only get what we need but entire sector */
- if (maxy>h) maxy=h; /* but no more than picture */
- nrep = maxy/VLINES; /* number of times we pull in */
- fpl=fopen(lumfn,"r"); /* try to open all our files */
- fp1=fopen(c1fn,"r");
- fp2=fopen(c2fn,"r");
- if (!fp1 || !fp2 || !fpl) { /* couldn't open */
- printf(" Unable to open one or more intermediate file(s) \n");
- cleanup(E_READ); }
-
- fread(&hl,16,1,fpl); /* get header data. we MAY actually use this someday!*/
- fread(&h1,16,1,fp1);
- fread(&h2,16,1,fp2);
- rgbuf[0]=Luma.im; /* set buffer pointer for conversion to to opal*/
- rgbuf[1]=Chroma1.im;
- rgbuf[2]=Chroma2.im;
-
- /* assume the Opal Screen is already made */
- if (!OScrn) cleanup(E_OVD); /* but check to make sure */
- dw= OScrn->Width; /* get these from Opal Screen structure */
- dh= OScrn->Height;
- /* below here updated for each pic, so loop on this ! */
- telltime("Starting file readback. Time so far=",clock1);
- for(i=0;i<nrep;i++) { /* take a 300K hunk of data and move it in */
- fread(Luma.im,w,VLINES,fpl); /* read in a hunk of data,64 lines */
- if ( w>2000) { /* handle chroma differently for Mode 5 */
- if (i==0) { /* first set of lines */
- a=fread(Chroma1.im,w/2,(VLINES/2)+1,fp1); /* one xtra line f/interp */
- a=fread(Chroma2.im,w/2,(VLINES/2)+1,fp2); }
- else {/* WE NEED ONE MORE LINE SO WE CAN INTERPOLATE LINE # VLINES-1!*/
- memcpy(Chroma1.im,lb1,w/2); /* copy the top line last time is bottom */
- memcpy(Chroma2.im,lb2,w/2); /* need this for seamless interp */
- a=fread(Chroma1.im+(w/2),w/2,(VLINES/2),fp1); /* read the rest from HD */
- a=fread(Chroma2.im+(w/2),w/2,(VLINES/2),fp2); /* half width half ht*/
- }
- memcpy(lb1,Chroma1.im+((w*VLINES)/4),w/2); /* get raw last line */
- memcpy(lb2,Chroma2.im+((w*VLINES)/4),w/2); /* becomes first line now */
- if (a< (VLINES/2)-1) cleanup(E_READ); /* we could not read all data */
- yi=(VLINES/2)+1; /*count lines backward starting with extra line */
- for(y=0;y<((VLINES/2)+1);y++){ /* do our interp, move& stretch lines */
- yi--; /* start from bottom near END */
- op1=Chroma1.im+(( yi+1)*w/2)-1;/* old pointer 1/2 way */
- np1=Chroma1.im+(yi*w*2)+w-2 ; /* destination pointer */
- op2=Chroma2.im+(( yi+1)*w/2)-1 ;/* old pointer 1/2 way */
- np2=Chroma2.im+(yi*w*2)+w-2 ; /* destination pointer */
- /* go DOWN in x, DOWN in Y. Don't paint ourselfs in a corner */
-
- *np1=*(np1+1)=*op1; /* set end points equal */
- *np2=*(np2+1)=*op2;
- for(x=1;x<(w/2);x++){/* do this #of times of current width */
- op1--; np1-=2; op2--; np2-=2; /* drop old ptr by 1 and new by 2 */
- *np1=*op1; *np2=*op2; /* set the even point equal */
- /* *(np1+1)=*op1; *(np2+1)=*op2; */ /* dont interp */
- np1[1]=(((short)op1[0])+((short) op1[1]))>>1;
- np2[1]=(((short)op2[0])+((short) op2[1]))>>1; /*
- this point and next point in X direction */
- } /* try sub divede by 2 with >>1 */
- }
-
- for(y=0;y<(VLINES+2);y+=2){ /* this reads between the lines */
- op1=Chroma1.im + (y*w);/* op=linebelow up=line above*/
- np1=op1+w; up1=np1+w; /* set pointers one finished line apart */
- op2=Chroma2.im + (y*w);
- np2=op2+w; up2=np2+w; /* set pointers one finished line apart */
- for(x=0;x<w;x++){ /* set odd lines by reading between even lines */
- *(np1++)=(((int)*(op1++))+((int)*(up1++)))>>1;
- *(np2++)=(((int)*(op2++))+((int)*(up2++)))>>1;
- /* the missing lines are the avg of lines above&below*/
- }
- } /* close for Y loop */
-
-
-
- } /* close w>2000 loop */
- else{ /* for modes 4,6 we have all bytes */
- a=fread(Chroma1.im,w,VLINES,fp1);
- a= fread(Chroma2.im,w,VLINES,fp2);
- if (a<VLINES) cleanup(E_READ); /* we could not read all data */
- }
- if ( !(i&7) ) printf("\n"); /* lf every 8 numbers */
- printf("%d ",i*VLINES);
-
- ycctorgb(w,VLINES,&Luma,&Chroma1,&Chroma2); /* convert it to RGB */
- RGBtoOV( OScrn,rgbuf,-1*cropx,(-1*cropy)+ (i*VLINES),w,VLINES); /* convert it */
-
- }
- printf ( " \n");
- telltime("Time to do all virtual processing ",clock1);
- fclose(fpl); /* close all files */
- fclose(fp1);
- fclose(fp2);
- remove(lumfn); remove(c1fn); remove(c2fn); /* remove temp files */
- free(lb1); free(lb2);/* let go of buffers we dont need them anymore */
- /* copy the data into the virtual screen */
- AutoSync24(asy);
- Err = (long)LowMemUpdate24 (OScrn,0);
- if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
- { AutoSync24 (asy);
- /* Err = (long)LowMemUpdate24 (OScrn,6); */
- }
- if ( (OScrn) && (fname) ){ /* we can save file */
- if (jpeg)
- a=SaveJPEG24(OScrn,fname,NULL, jpeg);
- else
- a=SaveIFF24(OScrn,fname, NULL,NULL);
- if (a) printf( "iff save error # %d couldn't save picture\n",a);
- else printf( "file saved as %s \n",fname);
- }
-
- if (Err < OL_ERR_MAXERR)
- { CloseScreen24 ();
- if (Err==OL_ERR_OUTOFMEM)
- printf ("Out of memory!! \n");
- else if (Err==OL_ERR_CANTCLOSE)
- printf("OpalVision Display in Use.\n");
- else
- printf("Error Displaying image!! \n");
- cleanup(E_OVD);
- }
-
- OVPriority();
- Delay(10);
-
-
-
- while ( *Button &0x040) { /* button for single show */
- Delay(10); }
- if ( backdrop){ /* we want to leave image as backdrop */
- AmigaPriority ();
- DualDisplay24 ();
- Delay (2L);
- LatchDisplay24 (TRUE);
- Delay (2L);
- }
- AmigaPriority();
- SingleDisplay24();
- FreeScreen24 (OScrn);
- CloseScreen24();
- return(0);
- }
-
-
-
- int DoOpal(int asy,int slide, char *fname) /* fill display and save OV */
- {
- int a,dw,dh,pic,slerr,orun;
- UBYTE *rgbp[4];
- long Err;
- /* assume the Opal Screen is already made */
- if (!OScrn) cleanup(E_OVD); /* but check to make sure */
- pic=1; slerr=0; orun=1; /* init variables */
- dw= OScrn->Width; /* get these from Opal Screen structure */
- dh= OScrn->Height;
- if (slide) pic= pstart; /* don't start at zero */
-
- /* below here updated for each pic, so loop on this ! */
- while (orun && (pic < 150)) { /* keep doing this */
- rgbp[0]= Luma.im; /* set image area pointers */
- rgbp[1]= Chroma1.im;
- rgbp[2]= Chroma2.im;
- TurnOpal(OScrn,rgbp,cropx,cropy,dw,dh,turn); /* turn it */
- telltime("Picture loading & Decoding took",clock1);
-
- /* copy the data into the virtual screen */
- AutoSync24(asy);
- Err = (long)LowMemUpdate24 (OScrn,0);
- if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
- { AutoSync24 (asy);
- /* Err = (long)LowMemUpdate24 (OScrn,6); */
- }
- if ( (OScrn) && (fname) ){ /* we can save file */
- if (jpeg)
- a=SaveJPEG24(OScrn,fname,NULL, jpeg);
- else
- a=SaveIFF24(OScrn,fname, NULL,NULL);
- if (a) printf( "iff save error # %d couldn't save picture\n",a);
- else printf( "file saved as %s \n",fname);
- }
-
- if (Err < OL_ERR_MAXERR)
- { CloseScreen24 ();
- if (Err==OL_ERR_OUTOFMEM)
- printf ("Out of memory!! \n");
- else if (Err==OL_ERR_CANTCLOSE)
- printf("OpalVision Display in Use.\n");
- else
- printf("Error Displaying image!! \n");
- cleanup(E_OVD);
- }
-
- pic++;
- if (slide ) {
-
- slerr=GetNextPic(pic,0);
- if (slerr ==9){
- printf("we hit last pic. Starting over\n");
- pic=1; Delay(60); /* go back and start over */
- slerr=GetNextPic(pic,0);
- }
- if(slerr) orun=0; /* get the next file, if error,quit */
- /* FadeOut24(25);*/
-
- }
- else orun=0;
- OVPriority();
- Delay(10);
-
- if ( !(*Button & 0x040)) { /* button down for SLIDE */
- Delay(30); /* debounse */
- if (!(*Button & 0x040 )) orun=0; /* get out, is held down */
- }
-
- }
- while ((*Button &0x040) && !(slide)){ /* button for single show */
- Delay(10); }
- if ( backdrop){ /* we want to leave image as backdrop */
- AmigaPriority ();
- DualDisplay24 ();
- Delay (2L);
- LatchDisplay24 (TRUE);
- Delay (2L);
-
- }
- FreeScreen24 (OScrn);
- CloseScreen24();
- return(0);
- }
-
- int GetNextPic(int pic,int res) /* slidesow, get next picture to OV */
- {
- static char *fn="CD0:PHOTO_CD/IMAGES/IMG0001.PCD";
- int i,wm,ht;
- if(fin) fclose(fin); /* if it is open, close it */
- fin=NULL;
- if((pic>199) || (pic<0)) return(999); /* pic too high */
- wm=w/192; /* use to switch */
- ht= (pic/100); /* convert to digits */
- pic -= ht * 100; /* get it to 100 */
- *(fn+24)= h+48;
-
- *(fn+25)=(pic/10)+48;
- *(fn+26)=(pic%10)+48;
- printf("filename is %s\n",fn);
-
- fin=fopen(fn,"r");
- if(!fin) return(9);
- switch(wm) { /* based on resolution */
- case 2 : SEEK(L_Head+L_Base16+1); break;
- case 4 : SEEK(L_Head+L_Base16+L_Base4+1) ; break;
- case 1 : SEEK(L_Head+1); break;
- default: return(13);
- }
- Luma.iwidth=Luma.iheight=0;
- Chroma1.iwidth=Chroma1.iheight=0;
- Chroma2.iwidth=Chroma2.iheight=0;
- i=readplain(w,h,&Luma,&Chroma1,&Chroma2);
- if (fin) { fclose(fin); fin=NULL; }
- /* printf( "plane read %d w %d h %d i \n",w,h,i); */
- if(i) return(i); /* an error here break */
- interpolate(&Chroma1);
- interpolate(&Chroma2);
- ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
-
- return(0); /* successful */
- }
-
- int TurnOpal( Oscr, rgbp, xos,yos,dw,dh,dir)
- struct OpalScreen *Oscr;
- UBYTE *rgbp[3]; /* pointers for decoded Photo CD data */
- int xos,yos,dw,dh,dir; /* offset and size of image, and dir 0=no 1=r else l
- do cropping here, if unable to open screen, stash in file and
- reload down the line */
- { /* this is to view images on edge. To save memory we only buffer
- 16 lines */
- long size,lines;
- int i,j,ystep;
- UBYTE *buf,*rgbuf[3],*rp,*gp,*bp; /* pointers into array */
- lines=16;
- size=h*3*lines; /* well do 16 lines (initially columns ) at a time */
- buf=malloc(size); /* try to allocate the memory */
- rp=rgbuf[0]=buf;
- gp=rgbuf[1]=buf+(h*lines);/* set pointer */
- bp=rgbuf[2]=buf+(h*lines*2);
-
- if ( !buf) {
- printf("can't allocate turn buffer, try closing some windows \n");
- cleanup(E_MEM);
- }
- if (crop) { xos *= -1; /* invert since pcd larger than Opal */
- yos *= -1;
- }
- if ( dir==0) {
- RGBtoOV ( OScrn,rgbp,xos,yos,w,h );
- return(3); /* do this step here */
- }
- if (turn==1) { /* right turn */
- /* start from bottom left j=column turned to row */
- for(j=0; j<w; j++){
- for(i=h-1; i>=0; i--) { /* count up from bottom build one line*/
- ystep=(i*w)+j;
- *rp++=*(rgbp[0]+ ystep); /* copy pixels for each color */
- *gp++=*(rgbp[1]+ ystep);
- *bp++=*(rgbp[2]+ ystep);
- }
- if( ( ( j& 0x0F )==0x0f) || (j == w-1)) { /* update ea 16 lines*/
- rp=rgbuf[0]; /* eset pointers to bases */
- gp=rgbuf[1];
- bp=rgbuf[2];
- RGBtoOV( Oscr,rgbuf,xos,yos+j-lines+1,h,lines); /* convert it */
-
- }
-
- }
- }
- else { /* left turn */
- /* start from bottom left j=column turned to row */
- for(j=w-1; j>=0; j--){
- for(i=0; i<h; i++) { /* count down build one line*/
- ystep=(i*w)+j;
- *rp++=*(rgbp[0]+ ystep); /* copy pixels for each color */
- *gp++=*(rgbp[1]+ ystep);
- *bp++=*(rgbp[2]+ ystep);
- }
- if( ( j& 0x0F )==0x00) { /* update ea 16 lines*/
- rp=rgbuf[0]; /* reset pointers to bases */
- gp=rgbuf[1];
- bp=rgbuf[2];
- RGBtoOV( Oscr,rgbuf,xos,yos+w-j-lines,h,lines); /* convert it */
-
- }
- }
- }
- free(buf); /* let it go, we dont need it anymore */
- return(j);
-
-
-
- }
-
- int storeplane(implane *imp,char *fn)
- { /* store a plane in a file, return 0 if OK, else error */
- FILE *fps;
- int a;
- fps = fopen(fn,"w"); /* open it */
- if (!fps) return(1); /* error if not open */
- a=fwrite( &ih,16,1,fps); /* write header, use default */
- a=fwrite( imp->im,imp->iwidth,imp->iheight,fps);
- fclose(fps); /* close the file no matter what */
- if ( a < imp->iheight) return (a+1);
- return(0); /* we are successful */
- }
-
- enum ERRORS readplain(w,h,l,c1,c2)
- dim w,h;
- implane *l,*c1,*c2;
- {
- dim i;
- byte *pl=0,*pc1=0,*pc2=0;
-
- if(l)
- { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) cleanup(E_INTERN);
- l->iwidth=w;
- l->iheight=h;
- pl=l->im;
- }
-
- if(c1)
- { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) cleanup(E_INTERN);
- c1->iwidth=w/2; /* Make sure theyre big enough */
- c1->iheight=h/2;
- pc1=c1->im;
- }
-
- if(c2)
- { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) cleanup(E_INTERN);
- c2->iwidth=w/2;
- c2->iheight=h/2;
- pc2=c2->im;
- }
-
- for(i=0;i<h/2;i++)
- {
- if(pl)
- {
- if(fread(pl,w,1,fin)<1) return(E_READ);
- pl+= l->mwidth;
-
- if(fread(pl,w,1,fin)<1) return(E_READ);
- pl+= l->mwidth;
- }
- else SKIPr(2*w);
-
- if(pc1)
- { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
- pc1+= c1->mwidth;
- }
- else SKIPr(w/2);
-
- if(pc2)
- { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
- pc2+= c2->mwidth;
- }
- else SKIPr(w/2);
-
-
- }
- #ifdef DEBUG
- fprintf(stderr,"R-Position %x\n",ftell(fin));
- #endif
- return E_NONE;
- }
-
-
- static void interpolate(implane *p)
- {
- dim w,h,x,y,yi,h2,w2;
- byte *optr,*nptr,*uptr;
-
- if ((!p) || (!p->im)) cleanup(E_INTERN);
-
- w=p->iwidth;
- h=p->iheight;
-
- if(p->mwidth < 2*w ) cleanup(E_INTERN);
- if(p->mheight < 2*h ) cleanup(E_INTERN);
-
-
- w2=p->iwidth =2*w;
- h2=p->iheight=2*h;/* cut some multiplications by doing once at start */
-
-
- for(y=0;y<h;y++) /* each line */
- {yi=h-1-y; /* start from bottom near END */
- optr=p->im+ yi*p->mwidth + (w-1);/* old pointer USES MAX WID starts 1/2 way*/
- nptr=p->im+((yi*p->mwidth)<<1) + (w2 - 2); /* starts near end and works back*/
-
- nptr[0]=nptr[1]=optr[0]; /* set these two end points to oldpoint*/
-
- for(x=1;x<w;x++)/* do this #of times of current width */
- { optr--; nptr-=2; /* drop old ptr by 1 and new by 2 */
- nptr[0]=optr[0]; /* set the even point equal */
- nptr[1]=(((short)optr[0])+((short)optr[1]))>>1; /* odd pt is avg between
- this point and next point in X direction */
- } /* try sub divede by 2 with >>1 */ }
-
- for(y=0;y<h-1;y++) /* this reads between the lines */
- {optr=p->im + ((y*p->mwidth)<<1);
- nptr=optr+p->mwidth;
- uptr=nptr+p->mwidth;
-
- for(x=0;x<w2;x++)
- *(nptr++)=(((short)*(optr++))+((short)*(uptr++)))>>1;
- }
-
- bcopy(p->im + (h2-2)*p->mwidth, p->im + (h2-1)*p->mwidth, w2);
-
- }
-
- void telltime(tmsg, clock1) /* tell elapsed time, array at start is passed */
- unsigned int clock1[2];
- char *tmsg;
- {
- unsigned int x;
- double t;
- x=timer(clock2); /* get time I came out of it */
- if( clock2[1] < clock1[1]) { /* take care of uS rollover */
- clock2[1]+= 1000000L;
- clock2[0]--; }
-
- clock2[1]-=clock1[1]; /* get diff in us */
- clock2[0]-=clock1[0];
- t=(double) (clock2[1]/1000000.0) +(double)clock2[0];
- printf( "%s %8.3f Sec. \n",tmsg,t);
- }
-
- static void ycctorgb(w,h,l,c1,c2)
- dim w,h;
- implane *l,*c1,*c2;
- {
- register dim x,y,i;
- register byte *pl,*pc1,*pc2;
- short red,green,blue;
- float L;
- static int init=0;
- static float XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
- /*
- if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) cleanup(E_INTERN);
- if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) cleanup(E_INTERN);
- if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) cleanup(E_INTERN);
- */
- if(do_sharp) sharpit(l);
-
-
- if(!init)
- {init=1;
- for(i=0;i<256;i++)
- { XL[i]=1.3584 * ((float)i );
- XC1[i]=2.2179 * (((float)i)-156.0);
- XC2[i]=1.8215 * (((float)i)-137.0);
- XC1g[i]= -0.194 * XC1[i];
- XC2g[i]= -0.509 * XC2[i];
- }
- }
-
-
-
- for(y=0;y<h;y++)
- {
- pl = l->im + y * l->mwidth;
- pc1= c1->im + y * c1->mwidth;
- pc2= c2->im + y * c2->mwidth;
-
- for(x=0;x<w;x++)
- {
- L = XL[*pl];
-
- red =L + XC2[*pc2];
- green=L + XC1g[*pc1] + XC2g[*pc2];
- blue =L + XC1[*pc1];
-
- NORM(red);
- NORM(green);
- NORM(blue);
-
- *(pl++ )=red;
- *(pc1++)=/*green */ green;
- *(pc2++)=blue;
- }
- /* printf("line %d raw is %d %d %d \n",y,*pl,*pc1,*pc2); */
- }
-
- }
-
-
- static void druckeid()
- {
- struct ph1 *d;
- char ss[100];
-
- SEEK(1);
- if(READBUF<1) cleanup(E_READ);
- d=(struct ph1 *)sbuffer;
-
- #define dr(feld,kennung) \
- strncpy(ss,feld,sizeof(feld));\
- ss[sizeof(feld)]=0;\
- fprintf(stderr,"%s: %s \n",kennung,ss);
- dr(d->id1,"Id1")
- dr(d->id2,"Id2")
- dr(d->id3,"Id3")
- dr(d->id4,"Id4")
- dr(d->id5,"Id5")
- #undef dr
- }
-
- struct pcdword
- { byte high,low;
- };
-
-
-
-
- struct pcdquad { byte len,highseq,lowseq,key;}; /* size=4 */
- struct pcdhqt { byte entries; struct pcdquad entry[256];}; /* size=1025*/
- struct myhqt { unsigned long seq,mask,len; byte key; }; /* size=13 */
-
-
- #define E ((unsigned long) 1)
-
-
- static void readhqtsub(source,ziel,anzahl)
- struct pcdhqt *source;
- struct myhqt *ziel;
- int *anzahl;
- {int i;
- struct pcdquad *sub;
- struct myhqt *help;
- *anzahl=source->entries+1;
-
- for(i=0;i<*anzahl;i++)
- {sub= source->entry+i;
- help=ziel+i;
-
- help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
- help->len = ((unsigned long) sub->len) +1;
-
- if(help->len > 16) cleanup(E_HUFF);
-
- help->key = sub->key;
- help->mask = ~ ( (E << (32-help->len)) -1);
-
- }
- #ifdef DEBUG
- for(i=0;i<*anzahl;i++)
- {help=ziel+i;
- fprintf(stderr,"H: %3d %08lx & %08lx (%2d) = %02x = %5d %8x\n",
- i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
- help->seq & (~help->mask));
- }
- #endif
-
- }
-
- static struct myhqt myhuffl[256],myhuff1[256],myhuff2[256];
- static int myhufflenl=0,myhufflen1=0,myhufflen2=0;
-
- static void readhqt(w,h,n)
- dim w,h,n;
- {
- byte *ptr; /* fix type to placate compiler 3-6-93 */
- int a;
- if ( n==3 ) { /* if for decompressing highest get 2 sectors */
- a=fread(sbuffer,1,4000,fin); }
- else a=READBUF; /* else, for second highest, get only 1 sector */
- if(a ==0 ) cleanup(E_READ);
- ptr = sbuffer;
-
- readhqtsub((struct pcdhqt *) ptr,myhuffl,&myhufflenl);
-
- if(n<2) return;
- ptr+= 4* myhufflenl;
- ptr++;
- readhqtsub((struct pcdhqt *) ptr,myhuff1,&myhufflen1);
- if(n<3) return;
- ptr+= 4* myhufflen1;
- ptr++;
- readhqtsub((struct pcdhqt *) ptr,myhuff2,&myhufflen2);
- /* printf( " Length of hqts %d\n",ptr-sbuffer); */
- }
-
-
- #define nextbuf { nptr=sbuffer; if(READBUF < 1) cleanup(E_READ);\
- }
- #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
- #define shiftout(n){ sreg<<=n; inh-=n; \
- while (inh<=24) \
- {checkbuf; \
- sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
- inh+=8;\
- }\
- }
-
- /* I think the following routine is screwed since it works OK up to
- its usage 3/8/93 readhqt not called anymire */
-
-
-
- static void decompress(w,h,f,f1,f2)
- dim w,h;
- implane *f,*f1,*f2;
- {
- register int i,htlen,sum;
- unsigned long sreg,maxwidth;
- unsigned int inh,n,zeile,segment,ident,j;
- struct myhqt *htptr,*hp;
-
- byte *nptr;
- byte *lptr;
-
- /* try bypass this so we can decompress Chroma only */
- /*
- if((!f) || (!f->im)) cleanup(E_INTERN);
- if((f->iheight < h) || (f->iwidth<w)) cleanup(E_INTERN); */
- maxwidth=f->mwidth;
- if (!f) maxwidth=w;
- sreg=0x0000;
- nextbuf;
- inh=32;
- lptr=0;
- shiftout(16);
- shiftout(16);
-
- n=0;
- for(;;) /* keeps going and going*/
- {
- if((sreg & 0xffffff00) == 0xfffffe00)
- {shiftout(24);
- ident=sreg>>16;
- shiftout(16);
-
- zeile=(ident>>1) & 0x1fff;
- segment=ident>>14;
- /* the loop passes here about once each line */
- /* if (!( zeile & 127)) /* do each 16th line */
- fprintf(stderr,"Ident %4x Zeile: %6d Segment %3d Pixels bisher: %d\n",
- ident,zeile,segment,n);*/
-
- if(lptr && (n!=maxwidth)) cleanup(E_SEQ1);
- n=0;
-
- /* zeile must mean height in pixel rows */
- if(zeile==h) return; /* WERE DONE */
-
- if(zeile > h) cleanup(E_SEQ2);
-
- switch(segment)
- {
- case 0: htlen=myhufflenl;
- htptr=myhuffl;
-
- if(!f ){ /* do this if luma not used */
- lptr=NULL;
- maxwidth=w;
-
-
- } /* to placate things */
- else {
- lptr=f->im + zeile*f->mwidth; /* set pointer */
- maxwidth=f->iwidth;
- }
- break;
-
- case 2: if(!f1) return; /* were doing MONOCHROME only */
- if ( virt && f && f1) { /* size 5, virtual mode
- and have NOT done a chroma hunk yet we need to do some stuff*/
- ih.width=w; ih.height=h; /* Luma plane is FULL size*/
- j= storeplane(f,lumfn);
- planefree(&Luma); /* free it up */
- f=0L; /* set luma plane to 0, we dont need it anymore */
- if (j) { printf("Error %d storing Luma file, too little disk space? \n",j);
- cleanup(E_WRITE); }
- ih.width=w/2; ih.height=h/2; /* chroma planes 1/4 size*/
-
- planealloc(f1,w/2,h/2); /* just do max detail1536x1024*/
- planealloc(f2,w/2,h/2); /* these two take about 3Meg*/
- for( j=0; j< 256; j++) { /* align lines to max width to conform */
- memcpy(f1->im+(j*w/2),C1t.im+(384*j),384); /* copy temps over */
- memcpy(f2->im+(j*w/2),C2t.im+(384*j),384); /* copy temps over */
- } /* space the 384x256 chroma to be interpolated */
- planefree(&C1t); /* get rid of temp chroma */
- planefree(&C2t);
- printf("Interpolating chroma \n");
- f1->iheight=f2->iheight=h/8; /* only 368x256*/
- f1->iwidth =f2->iwidth =w/8;
- interpolate(f1);
- interpolate(f1);
- interpolate(f2);
- interpolate(f2); /* NOW interpolate it out x4 each dir*/
- printf("really Starting to decompress Chroma\n");
-
- /* we are all ready to go */
- /* BTW f=Luma, f1=Chroma1 and f2=Chroma2 planes */
- }
- if (!f1->im) cleanup(E_SEQ7); /* cover allocation errors */
- lptr=f1->im + (zeile>>1)*f1->mwidth;
- maxwidth=f1->iwidth;
- htlen=myhufflen1;
- htptr=myhuff1;
- break;
-
- case 3: if(!f2) cleanup(E_SEQ7);
- if(!f2->im) cleanup(E_SEQ7);
- lptr=f2->im + (zeile>>1)*f2->mwidth;
- maxwidth=f2->iwidth;
- htlen=myhufflen2;
- htptr=myhuff2;
- if(zeile >= (h-9)) return; /* break off a little early */
- /* TEMP FIX FOR BUG IN SYSTEM READ OF LAST SECTOR.
- CHROMA RESOLUTION SLIGHTLY LOWER ON BOTTOM 4 LINES */
- break;
-
- default:cleanup(E_SEQ3);
- } /* end of segment case statement */
- }
- else
- { /* DECOMPRESS THE PIXEL */
- if(n>maxwidth)/* cleanup(E_SEQ4);*/
- {printf("Nonfatal err4 line %d seg %d \n",zeile,segment); return; }
- for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
- if(i>=htlen) cleanup(E_SEQ5);
- if (lptr) { /* if we are not saving, skip this much */
- sum=((int)(*lptr)) + ((int)hp->key);
- /* add decompressed data to pixel */
- *(lptr++) = sum & 0xff ;
- /* ---THIS SEEMS TO HAVE FIXED THE PROBLEM,
- BAZZ 3-10-93! CHANGING NORM TO & 0XFF ; */
- n++;
- }
- shiftout(hp->len);
-
- } /* END OF ELSE ROUTINE */
-
- } /* END OF FOR(;;) INDEFINATE LOOP */
-
-
-
- } /* END OF DECOMPRESS SUBROUTINE */
-
-
-
-
- static void clear(l,n)
- implane *l;
- int n;
- { dim x,y;
- byte *ptr;
- /* l->iwidth=l->mwidth;
- l->iheight=l->mheight;
- */
- ptr=l->im;
- for (x=0;x<l->mwidth;x++)
- for (y=0; y<l->mheight;y++)
- *(ptr++)=n;
- }
-
-
- static void sharpit(l)
- implane *l;
- {int x,y,h,w,mw,akk;
- byte f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
-
- if((!l) || (!l->im)) cleanup(E_INTERN);
- if(l->iwidth > slen) cleanup(E_INTERN);
-
- old=f1; akt=f2;
- h=l->iheight;
- w=l->iwidth;
- mw=l->mwidth;
-
- for(y=1;y<h-1;y++)
- {
- ptr=l->im+ y*mw;
- optr=ptr-mw;
- work=akt;
-
- *(work++)= *(ptr++);
- for(x=1;x<w-1;x++)
- { akk = 5*((int)ptr[0])- ((int)ptr[1]) - ((int)ptr[-1])
- - ((int)ptr[mw]) - ((int)ptr[-mw]);
- NORM(akk);
- *(work++)=akk;
- ptr++;
- }
-
- *(work++)= *(ptr++);
-
- if(y>1) bcopy(old,optr,w);
- help=old;old=akt;akt=help;
-
- }
-
- bcopy(old,optr+mw,w);
- }
-
- int Display_Mode_Check (void)
- { /* see if we are in high res */
- struct MonitorInfo MonitorInfo;
- DisplayInfoHandle Handle;
- ULONG ModeID;
- LONG Result;
-
- GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library",36L);
- if (GfxBase==NULL) return (TRUE);
- IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library",0L);
- if (IntuitionBase==NULL)
- { CloseLibrary ((struct Library *)GfxBase);
- return (TRUE);
- }
- ModeID = GetVPModeID (&IntuitionBase->FirstScreen->ViewPort);
- Handle = FindDisplayInfo (ModeID);
- Result = GetDisplayInfoData (Handle,(UBYTE *)&MonitorInfo,
- sizeof (struct MonitorInfo),DTAG_MNTR,NULL);
-
- /* If line frequency if >15Khz, a backdrop
- * cannot be displayed.
- */
-
- if (MonitorInfo.TotalColorClocks<220)
- { CloseLibrary ((struct Library *)GfxBase);
- CloseLibrary ((struct Library *)IntuitionBase);
- return (FALSE);
- }
- CloseLibrary ((struct Library *)GfxBase);
- CloseLibrary ((struct Library *)IntuitionBase);
- return (TRUE);
- }
-
-